home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 1128 < prev    next >
Encoding:
Text File  |  1996-08-06  |  13.7 KB  |  469 lines

  1. Path: tank.news.pipex.net!pipex!demon!le-vamp.demon.co.uk
  2. From: Kurt@le-vamp.demon.co.uk (Kurt Frary)
  3. Newsgroups: comp.lang.c++
  4. Subject: help borland c++ and tasm ?
  5. Date: Tue, 09 Jan 1996 13:31:16 GMT
  6. Message-ID: <821194253.362@le-vamp.demon.co.uk>
  7. Reply-To: kurt@le-vamp.demon.co.uk
  8. NNTP-Posting-Host: le-vamp.demon.co.uk
  9. X-NNTP-Posting-Host: le-vamp.demon.co.uk
  10. X-Newsreader: Forte Agent .99c/32.126
  11.  
  12. If anyone can help it would be much appreciated!
  13.  
  14.  
  15.  
  16.  
  17. these are the errors I get:-
  18.  
  19. Linking cpuid.exe:
  20. Linker Warning: DOSSEG directive ignored in module
  21. X:\KURT'S~1\KURT'S~1\CPUIDP~1\cpuid3a.asm
  22. Linker Error: Undefined symbol _printf in module CPUID3B.C
  23. Linker Error: Undefined symbol _features_edx in module CPUID3B.C
  24. Linker Error: Undefined symbol _cpu_signature in module CPUID3B.C
  25. Linker Error: Undefined symbol F_LXRSH@ in module CPUID3B.C
  26. Linker Error: Undefined symbol _cpu_type in module CPUID3B.C
  27. Linker Error: Undefined symbol _intel_CPU in module CPUID3B.C
  28. Linker Error: Undefined symbol _fpu_type in module CPUID3B.C
  29. Linker Error: Undefined symbol _cpuid_flag in module CPUID3B.C
  30. Linker Error: Undefined symbol _get_fpu_type in module CPUID3B.C
  31. Linker Error: Undefined symbol _get_cpu_type in module CPUID3B.C
  32.  
  33.  
  34.  
  35. Here's the C source code as you can see it is from intel, I create a
  36. project and add these two file and it will not compile, these are the
  37. only two files in the project!
  38.  
  39. /* Filename:    cpuid3b.c                     */
  40. /* Copyright 1994 by Intel Corp.                 */
  41. /*                                  */
  42. /* This program has been developed by Intel Corporation.   */
  43. /*                                  */
  44. /* Intel specifically disclaims all warranties, express or     */
  45. /* implied, and all liability, including consequential and other */
  46. /* indirect damages, for the use of this code, including     */
  47. /* liability for infringement of any proprietary rights, and     */
  48. /* including the warranties of merchantability and fitness for a */
  49. /* particular purpose.  Intel does not assume any responsibility */
  50. /* for any errors which may appear in this code nor any         */
  51. /* responsibility to update it.                     */
  52. /*                                  */
  53. /* This program contains three parts:                 */
  54. /* Part 1: Identifies CPU type in the variable _cpu_type:     */
  55. /*                                  */
  56. /* Part 2: Identifies FPU type in the variable _fpu_type:     */
  57. /*                                  */
  58. /* Part 3: Prints out the appropriate message.             */
  59. /*                                  */
  60. /* This program has been tested with the Microsoft C compiler.     */
  61. /* If this code is compiled with no options specified and linked */
  62. /* with the cpuid3a module, it correctly identifies the current     */
  63. /* Intel 8086/8088, 80286, 80386, 80486, and Pentium(tm)     */
  64. /* processors in the real-address mode.                 */
  65.  
  66. #define FPU_FLAG    0x0001
  67. #define VME_FLAG    0x0002
  68. #define PSE_FLAG    0x0008
  69. #define MCE_FLAG    0x0080
  70. #define CMPXCHG8B_FLAG    0x0100
  71. #define APIC_FLAG    0x0200
  72.  
  73. extern char cpu_type;
  74. extern char fpu_type;
  75. extern char cpuid_flag;
  76. extern char intel_CPU;
  77. extern char vendor_id[12];
  78. extern long cpu_signature;
  79. extern long features_ecx;
  80. extern long features_edx;
  81. extern long features_ebx;
  82.  
  83. main() {
  84.     get_cpu_type();
  85.     get_fpu_type();
  86.     print();
  87. }
  88.  
  89. print() {
  90.     printf("This system has a");
  91.     if (cpuid_flag == 0) {
  92.     switch (cpu_type) {
  93.     case 0:
  94.         printf("n 8086/8088 processor");
  95.         if (fpu_type) printf(" and an 8087 math coprocessor");
  96.         break;
  97.     case 2:
  98.         printf("n 80286 processor");
  99.         if (fpu_type) printf(" and an 80287 math coprocessor");
  100.         break;
  101.     case 3:
  102.         printf("n 80386 processor");
  103.         if (fpu_type == 2)
  104.         printf(" and an 80287 math coprocessor");
  105.         else if (fpu_type)
  106.         printf(" and an 80387 math coprocessor");
  107.         break;
  108.     case 4:
  109.         if (fpu_type) printf("n 80486DX, 80486DX2 processor or \
  110. 80487SX math coprocessor");
  111.         else printf("n 80486SX processor");
  112.         break;
  113.     default:
  114.         printf("n unknown processor");
  115.     }
  116.     } else {
  117.     /* using cpuid instruction */
  118.     if (intel_CPU) {
  119.         if (cpu_type == 4) {
  120.         switch ((cpu_signature>>4)&0xf) {
  121.         case  0:
  122.         case  1:
  123.             printf(" Genuine Intel486(TM) DX processor");
  124.             break;
  125.         case  2:
  126.             printf(" Genuine Intel486(TM) SX processor");
  127.             break;
  128.         case  3:
  129.             printf(" Genuine IntelDX2(TM) processor");
  130.             break;
  131.         case  4:
  132.             printf(" Genuine Intel486(TM) processor");
  133.             break;
  134.         case  5:
  135.             printf(" Genuine IntelSX2(TM) processor");
  136.             break;
  137.         case  7:
  138.             printf(" Genuine Write-Back Enhanced \
  139. IntelDX2(TM) processor");
  140.             break;
  141.         case  8:
  142.             printf(" Genuine IntelDX4(TM) processor");
  143.             break;
  144.         default:
  145.             printf(" Genuine Intel486(TM) processor");
  146.         }
  147.         } else if (cpu_type == 5)
  148.         printf(" Genuine Intel Pentium(TM) processor");
  149.         else
  150.         printf("n unknown Genuine Intel processor");
  151.         printf("\nProcessor Family: %X", cpu_type);
  152.         printf("\nModel:            %X", (cpu_signature>>4)&0xf);
  153.         printf("\nStepping:         %X\n", cpu_signature&0xf);
  154.         if (cpu_signature & 0x1000)
  155.         printf("\nThe processor is an OverDrive(TM) upgrade \
  156. processor");
  157.         else if (cpu_signature & 0x2000)
  158.         printf("\nThe processor is the upgrade processor \
  159. in a dual processor system");
  160.         if (features_edx & FPU_FLAG)
  161.         printf("\nThe processor contains an on-chip FPU");
  162.         if (features_edx & MCE_FLAG)
  163.         printf("\nThe processor supports Machine Check \
  164. Exceptions");
  165.         if (features_edx & CMPXCHG8B_FLAG)
  166.         printf("\nThe processor supports the CMPXCHG8B \
  167. instruction");
  168.         if (features_edx & VME_FLAG)
  169.         printf("\nThe processor supports Virtual Mode \
  170. Extensions");
  171.         if (features_edx & PSE_FLAG)
  172.         printf("\nThe processor supports Page Size \
  173. Extensions");
  174.         if (features_edx & APIC_FLAG)
  175.         printf("\nThe processor contains an on-chip APIC");
  176.     } else {
  177.         printf("t least an 80486 processor.\nIt does not \
  178. contain a Genuine Intel part and as a result, the\nCPUID detection \
  179. information cannot be determined at this time.");
  180.     }
  181.     }
  182.     printf("\n");
  183. }
  184. 
  185.  
  186.  
  187.  
  188.  
  189. Here's the assembler!
  190.  
  191. ;    Filename:    cpuid3a.asm
  192. ;    Copyright 1993, 1994 by Intel Corp.
  193. ;
  194. ;    This program has been developed by Intel Corporation.  
  195. ;   Intel has intellectual property
  196. ;    rights which it may assert if another manufacturer's processor
  197. ;    mis-identifies itself as being "GenuineIntel" when the CPUID
  198. ;    instruction is executed.
  199. ;
  200. ;    Intel specifically disclaims all warranties, express or
  201. ;    implied, and all liability, including consequential and other
  202. ;    indirect damages, for the use of this code, including
  203. ;    liability for infringement of any proprietary rights, and
  204. ;    including the warranties of merchantability and fitness for a
  205. ;    particular purpose.  Intel does not assume any responsibility
  206. ;    for any errors which may appear in this code nor any
  207. ;    responsibility to update it.
  208. ;
  209. ;    This code contains two procedures:
  210. ;    _get_cpu_type: Identifies processor type in _cpu_type:
  211. ;        0=8086/8088 processor
  212. ;        2=Intel 286 processor
  213. ;        3=Intel386(TM) family processor
  214. ;        4=Intel486(TM) family processor
  215. ;        5=Pentium(TM) family processor
  216. ;
  217. ;    _get_fpu_type: Identifies FPU type in _fpu_type:
  218. ;        0=FPU not present
  219. ;        1=FPU present
  220. ;        2=287 present (only if _cpu_type=3)
  221. ;        3=387 present (only if _cpu_type=3)
  222. ;
  223. ;    This program has been tested with the MASM assembler.
  224. ;    This code correctly detects the current Intel 8086/8088,
  225. ;    80286, 80386, 80486, and Pentium(tm) processors in the
  226. ;    real-address mode.
  227. ;
  228. ;    To assemble this code with TASM, add the JUMPS directive.
  229.     jumps            ; Uncomment this line for TASM
  230.  
  231.  
  232.     TITLE    cpuid3
  233.     DOSSEG
  234.     .model    small
  235.  
  236. CPU_ID    MACRO
  237.     db    0fh        ; Hardcoded CPUID instruction
  238.     db    0a2h
  239. ENDM
  240.  
  241.     .data
  242.     public    _cpu_type
  243.     public    _fpu_type
  244.     public    _cpuid_flag
  245.     public    _intel_CPU
  246.     public    _vendor_id
  247.     public    _cpu_signature
  248.     public    _features_ecx
  249.     public    _features_edx
  250.     public    _features_ebx
  251. _cpu_type    db    0
  252. _fpu_type    db    0
  253. _cpuid_flag    db    0
  254. _intel_CPU    db    0
  255. _vendor_id    db    "------------"
  256. intel_id    db    "GenuineIntel"
  257. _cpu_signature    dd    0
  258. _features_ecx    dd    0
  259. _features_edx    dd    0
  260. _features_ebx    dd    0
  261. fp_status    dw    0
  262.  
  263.     .code
  264.     .8086
  265.  
  266. ;*********************************************************************
  267.  
  268.     public    _get_cpu_type
  269. _get_cpu_type    proc
  270.  
  271. ;    This procedure determines the type of processor in a system
  272. ;    and sets the _cpu_type variable with the appropriate
  273. ;    value.  If the CPUID instruction is available, it is used
  274. ;    to determine more specific details about the processor.
  275. ;    All registers are used by this procedure, none are preserved.
  276. ;    To avoid AC faults, the AM bit in CR0 must not be set.
  277.  
  278. ;    Intel 8086 processor check
  279. ;    Bits 12-15 of the FLAGS register are always set on the
  280. ;    8086 processor.
  281.  
  282. check_8086:
  283.     pushf            ; push original FLAGS
  284.     pop    ax        ; get original FLAGS
  285.     mov    cx, ax        ; save original FLAGS
  286.     and    ax, 0fffh    ; clear bits 12-15 in FLAGS
  287.     push    ax        ; save new FLAGS value on stack
  288.     popf            ; replace current FLAGS value
  289.     pushf            ; get new FLAGS
  290.     pop    ax        ; store new FLAGS in AX
  291.     and    ax, 0f000h    ; if bits 12-15 are set, then
  292.     cmp    ax, 0f000h    ;   processor is an 8086/8088
  293.     mov    _cpu_type, 0    ; turn on 8086/8088 flag
  294.     je    end_cpu_type    ; jump if processor is 8086/8088
  295.  
  296. ;    Intel 286 processor check
  297. ;    Bits 12-15 of the FLAGS register are always clear on the
  298. ;    Intel 286 processor in real-address mode.
  299.  
  300.     .286
  301. check_80286:
  302.     or    cx, 0f000h    ; try to set bits 12-15
  303.     push    cx        ; save new FLAGS value on stack
  304.     popf            ; replace current FLAGS value
  305.     pushf            ; get new FLAGS
  306.     pop    ax        ; store new FLAGS in AX
  307.     and    ax, 0f000h    ; if bits 12-15 are clear
  308.     mov    _cpu_type, 2    ; processor=80286, turn on 80286 flag
  309.     jz    end_cpu_type    ; if no bits set, processor is 80286
  310.  
  311. ;    Intel386 processor check
  312. ;    The AC bit, bit #18, is a new bit introduced in the EFLAGS
  313. ;    register on the Intel486 processor to generate alignment
  314. ;    faults.
  315. ;    This bit cannot be set on the Intel386 processor.
  316.  
  317.     .386            ; it is safe to use 386 instructions
  318. check_80386:
  319.     pushfd            ; push original EFLAGS
  320.     pop    eax        ; get original EFLAGS
  321.     mov    ecx, eax    ; save original EFLAGS
  322.     xor    eax, 40000h    ; flip AC bit in EFLAGS
  323.     push    eax        ; save new EFLAGS value on stack
  324.     popfd            ; replace current EFLAGS value
  325.     pushfd            ; get new EFLAGS
  326.     pop    eax        ; store new EFLAGS in EAX
  327.     xor    eax, ecx    ; can't toggle AC bit, processor=80386
  328.     mov    _cpu_type, 3    ; turn on 80386 processor flag
  329.     jz    end_cpu_type    ; jump if 80386 processor
  330.  
  331.     push    ecx
  332.     popfd            ; restore AC bit in EFLAGS first
  333.  
  334. ;    Intel486 processor check
  335. ;    Checking for ability to set/clear ID flag (Bit 21) in EFLAGS
  336. ;    which indicates the presence of a processor with the CPUID
  337. ;    instruction.
  338.  
  339.     .486
  340. check_80486:
  341.     mov    _cpu_type, 4    ; turn on 80486 processor flag
  342.     mov    eax, ecx    ; get original EFLAGS
  343.     xor    eax, 200000h    ; flip ID bit in EFLAGS
  344.     push    eax        ; save new EFLAGS value on stack
  345.     popfd            ; replace current EFLAGS value
  346.     pushfd            ; get new EFLAGS
  347.     pop    eax        ; store new EFLAGS in EAX
  348.     xor    eax, ecx    ; can't toggle ID bit,
  349.     je    end_cpu_type    ; processor=80486
  350.  
  351. ;    Execute CPUID instruction to determine vendor, family,
  352. ;    model, stepping and features.  For the purpose of this
  353. ;    code, only the initial set of CPUID information is saved.
  354.  
  355.     mov    _cpuid_flag, 1    ; flag indicating use of CPUID inst.
  356.     push    ebx        ; save registers
  357.     push    esi
  358.     push    edi
  359.     mov    eax, 0        ; set up for CPUID instruction
  360.     CPU_ID            ; get and save vendor ID
  361.  
  362.     mov    dword ptr _vendor_id, ebx
  363.     mov    dword ptr _vendor_id[+4], edx
  364.     mov    dword ptr _vendor_id[+8], ecx
  365.  
  366.     mov    si, ds
  367.     mov    es, si
  368.  
  369.     mov    si, offset _vendor_id
  370.     mov    di, offset intel_id
  371.     mov    cx, 12        ; should be length intel_id
  372.     cld            ; set direction flag
  373.     repe    cmpsb        ; compare vendor ID to "GenuineIntel"
  374.     jne    end_cpuid_type    ; if not equal, not an Intel processor
  375.  
  376.     mov    _intel_CPU, 1    ; indicate an Intel processor
  377.     cmp    eax, 1        ; make sure 1 is valid input for CPUID
  378.     jl    end_cpuid_type    ; if not, jump to end
  379.     mov    eax, 1
  380.     CPU_ID            ; get family/model/stepping/features
  381.     mov    _cpu_signature, eax
  382.     mov    _features_ebx, ebx
  383.     mov    _features_edx, edx
  384.     mov    _features_ecx, ecx
  385.  
  386.     shr    eax, 8        ; isolate family
  387.     and    eax, 0fh
  388.     mov    _cpu_type, al    ; set _cpu_type with family
  389.  
  390. end_cpuid_type:
  391.     pop    edi        ; restore registers
  392.     pop    esi
  393.     pop    ebx
  394.  
  395.     .8086
  396. end_cpu_type:
  397.     ret
  398. _get_cpu_type    endp
  399.  
  400. ;*********************************************************************
  401.  
  402.     public    _get_fpu_type
  403. _get_fpu_type    proc
  404.  
  405. ;    This procedure determines the type of FPU in a system
  406. ;    and sets the _fpu_type variable with the appropriate value.
  407. ;    All registers are used by this procedure, none are preserved.
  408.  
  409. ;    Coprocessor check
  410. ;    The algorithm is to determine whether the floating-point
  411. ;    status and control words are present.  If not, no
  412. ;    coprocessor exists.  If the status and control words can
  413. ;    be saved, the correct coprocessor is then determined
  414. ;    depending on the processor type.  The Intel386 processor can
  415. ;    work with either an Intel287 NDP or an Intel387 NDP.
  416. ;    The infinity of the coprocessor must be checked to determine
  417. ;    the correct coprocessor type.
  418.  
  419.     fninit            ; reset FP status word
  420.     mov    fp_status, 5a5ah; initialize temp word to non-zero
  421.     fnstsw    fp_status    ; save FP status word
  422.     mov    ax, fp_status    ; check FP status word
  423.     cmp    al, 0        ; was correct status written
  424.     mov    _fpu_type, 0    ; no FPU present
  425.     jne    end_fpu_type
  426.  
  427. check_control_word:
  428.     fnstcw    fp_status    ; save FP control word
  429.     mov    ax, fp_status    ; check FP control word
  430.     and    ax, 103fh    ; selected parts to examine
  431.     cmp    ax, 3fh        ; was control word correct
  432.     mov    _fpu_type, 0
  433.     jne    end_fpu_type    ; incorrect control word, no FPU
  434.     mov    _fpu_type, 1
  435.  
  436. ;    80287/80387 check for the Intel386 processor
  437.  
  438. check_infinity:
  439.     cmp    _cpu_type, 3
  440.     jne    end_fpu_type
  441.     fld1            ; must use default control from FNINIT
  442.     fldz            ; form infinity
  443.     fdiv            ; 8087/Intel287 NDP say +inf = -inf
  444.     fld    st        ; form negative infinity
  445.     fchs            ; Intel387 NDP says +inf <> -inf
  446.     fcompp            ; see if they are the same
  447.     fstsw    fp_status    ; look at status from FCOMPP
  448.     mov    ax, fp_status
  449.     mov    _fpu_type, 2    ; store Intel287 NDP for FPU type
  450.     sahf            ; see if infinities matched
  451.     jz    end_fpu_type    ; jump if 8087 or Intel287 is present
  452.     mov    _fpu_type, 3    ; store Intel387 NDP for FPU type
  453. end_fpu_type:
  454.     ret
  455. _get_fpu_type    endp
  456.  
  457.     end
  458. 
  459.  
  460.  
  461.  
  462.  
  463. MM MM   A    SS K K   EEE  RR        
  464. M M M  A A  S    K K  E    R R
  465. M   M  AAA   S   KK   EEE  RR             
  466. M   M  A A    S  K K  E    R R
  467. M   M  A A  SS   K K  EEE  R R  :)
  468.  
  469.